/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License.You may obtain a copy of the License at
	http://www.mozilla.org/MPL/MPL-1.1.html
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import org.aswing.Icon;

import com.bourre.events.EventBroadcaster;
import com.bourre.events.EventType;

import fvaswing.components.alert.FvAlertButton;
import fvaswing.components.alert.FvAlertEvent;
import fvaswing.components.alert.FvAlertType;
import fvaswing.components.alert.FvAlertView;

/**
 * <strong>Alert</strong> dialog box.
 * 
 * <p>The Alert control is <strong>modal</strong>, which means it will retain 
 * focus until the user closes it.
 * 
 * <p>Is connected to <strong>Fever Localisation API</strong>
 * 
 * {@code
 *	public function test() : Void
 *	{
 *		var alert : FvAlert = new FvAlert( FvAlertType.OK_ONLY );
 *		alert.message = "Delete this file";
 *		alert.title = "Caution";
 *		alert.addListener( this, _onResult );
 *		alert.enabledBlurEffect = true;
 *		alert.open( );
 *	}
 *	
 *	private function _onResult( event : FvAlertEvent ) : Void
 *	{
 *		if( event.getButton() == FvAlert.BUTTON_YES )
 *		{
 *			//do something
 *		}
 *	}
 *	
 * }
 * 
 * @see fvaswing.components.alert.FvAlertType
 * @see fvaswing.components.alert.FvAlertButton
 * 
 * @author Romain Ecarnot
 */
class fvaswing.components.FvAlert extends FvAlertView
{
	//-------------------------------------------------------------------------
	// Events definition
	//-------------------------------------------------------------------------
	
	/** Event type braodcasted when alert is closed. */	
	public static var onAlertClosedEvent : EventType = new EventType( 'onAlertClosed' );
	
	
	//-------------------------------------------------------------------------
	// Private properties
	//-------------------------------------------------------------------------
	
	private var _oEB : EventBroadcaster;
	
	private var _alertType : FvAlertType;
	private var _defaultFlag : FvAlertButton;
	private var _logicalFlag : FvAlertButton;
	
	private var _alertMessage : String;
	private var _alertTitle : String;
	private var _icon : Icon;	private var _enabledBlur : Boolean;
	
	private var _opened : Boolean;
	
	
	//-------------------------------------------------------------------------
	// Public Properties
	//-------------------------------------------------------------------------
	
	/** Height of each Alert button, in pixels. */
	public static var buttonHeight : Number = 22;
	
	/** Width of each Alert button, in pixels. */
	public static var buttonWidth : Number = 70;
	
	
	/**
	 * Defines which buttons are displayed in next alert open.
	 * 
	 * <p>Possible values are : 
	 * <ul>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#OK_ONLY}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#OK_CANCEL}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#YES_NO}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#YES_NO_CANCEL}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#ABORT_RETRY_IGNORE}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#RETRY_CANCEL}</li>
	 * </ul>
	 * 
	 * <p> If no valid flag is passed, use 
	 * <strong>{@link fvaswing.components.alert.FvAlertType#OK_ONLY}</strong>.
	 */
	public function get alertType() : FvAlertType { return _alertType; }
	public function set alertType( type : FvAlertType ) : Void { _alertType = type; }
	
	/**
	 * Specify the default button ( button which have the focus when alert open )
	 * 
	 * <p>Possible values are : 
	 * <ul>
	 *   <li>{@link fvaswing.components.alert.FvAlertButton#ABORT}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertButton#CANCEL}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertButton#IGNORE}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertButton#OK}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertButton#NO}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertButton#RETRY}</li>	 *   <li>{@link fvaswing.components.alert.FvAlertButton#YES}</li>
	 * </ul>
	 */
	public function get defaultButton() : FvAlertButton { return _defaultFlag; }
	public function set defaultButton( flag : FvAlertButton ) : Void { _defaultFlag = flag; }
	
	/**
	 * Indicates the alert message to be displayed.
	 */
	public function get message() : String { return _alertMessage; }
	public function set message( str : String ) : Void { _alertMessage = str; }
	
	/**
	 * Indicates the alert dialog caption.
	 */
	public function get title() : String { return _alertTitle; }
	public function set title( str : String ) : Void { _alertTitle = str; }
	
	/**
	 * Indicates the icon to be displayed in alert message.
	 */
	public function get icon() : Icon { return _icon; }
	public function set icon( iconObject : Icon ) : Void { _icon = iconObject; }
	
	/**
	 * Indicates if a BlurEffect is apply under FvAlert dialog box. 
	 * ( default {@code true} )
	 */
	public function set enabledBlurEffect( b : Boolean ) : Void { _enabledBlur = b; }
	public function get enabledBlurEffect() : Boolean { return _enabledBlur; }
	
	
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Creates and show an new alert dialog box.
	 * 
	 * @param text The alert message
	 * @param title The alert window title
	 * @param type The alert dialog type, possible values are : 
	 * <ul>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#OK_ONLY}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#OK_CANCEL}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#YES_NO}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#YES_NO_CANCEL}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#ABORT_RETRY_IGNORE}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#RETRY_CANCEL}</li>
	 * </ul>
	 * 
	 * @param closeHandler The alert result listener
	 * @param icon The Icon to display in alert box
	 */
	public static function show( 
		text : String, 
		caption : String, 
		type : FvAlertType, 
		listener, 
		customIcon : Icon, 
		defaultFlag : FvAlertButton ) : FvAlert
	{
		var o : FvAlert = new FvAlert(  );
		o.title = caption;
		o.message = text;
		o.alertType =  type;
		o.defaultButton = defaultFlag;
		o.icon = customIcon;
		o.addListener( listener );
		o.open();
		
		return o;
	}
	
	/**
	 * Constructor.
	 * 
	 * @param type The alert dialog type, possible values are : 
	 * <ul>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#OK_ONLY}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#OK_CANCEL}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#YES_NO}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#YES_NO_CANCEL}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#ABORT_RETRY_IGNORE}</li>
	 *   <li>{@link fvaswing.components.alert.FvAlertType#RETRY_CANCEL}</li>
	 * </ul>
	 */
	public function FvAlert ( type : FvAlertType )
	{
		_oEB = new EventBroadcaster( this );
		
		_alertType = type;
		_opened = false;
	}
	
	/**
	 * Adds listener to close alert event.
	 */	
	public function addListener( listener ) : Void
	{
		var a : Array = [ onAlertClosedEvent ].concat( arguments );
		_oEB.addEventListener.apply( _oEB, a );
	}
	
	/**
	 * Remove the specified event listener.
	 * 
	 * @param listener the listener which will be removed.
	 */
	public function removeListener( listener ) : Void
	{
		_oEB.removeEventListener( onAlertClosedEvent, listener );
	}
	
	/**
	 * Indicates if current alert instance is opened or not.
	 * @return {@code true} if alert is opened.
	 */
	public function isOpen() : Boolean
	{
		return _opened;	
	}
	
	/**
	 * Displays the alert window.
	 * 
	 * <p>The buttons label are automatically update
	 */
	public function open() : Void
	{
		if( _opened ) return;
		
		FvAlertView.getInstance()._openDialog( 
			this,  _alertType, _alertTitle, _alertMessage, _defaultFlag, _icon, _enabledBlur 
		);
		
		_opened = true;
	}
	
	/**
	 * Closes the alert window.
	 * 
	 * <p> When user click on 'close button', the {@link #ON_ALERT_CLOSED} event 
	 * is dispatched with {@link #BUTTON_CANCEL} id.
	 */
	public function close() : Void
	{
		_dispatchResult( FvAlertButton.CANCEL );
		_closeDialog();
	}
	
	/**
	 * Forces the dialog to be closed.
	 */
	public function fireClose( button : FvAlertButton ) : Void
	{
		_dispatchResult( button );
	}
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	private function  _dispatchResult( id : FvAlertButton ) : Void
	{
		_opened = false;
		
		_oEB.broadcastEvent( new FvAlertEvent( onAlertClosedEvent, this, id ) );
	}
	
}